import request from "@/utils/request.js";
import qs from "qs";

/**
 * 通用数据请求方法
 * @description 该函数提供了一种通用的方式来发送 HTTP 请求。它接受一个参数对象，该对象包含了请求的配置信息，如 URL、请求方法、请求参数和响应类型。
 * @param {String} url 请求url
 * @param {String} method 请求类型,如"get","post". isFormData为true时默认为post.
 * @param {String} params 请求携带的参数
 * @param {Boolean} isFormData 是否是formData的数据提交.会修改method\header\params相关格式及内容
 * @param {String} contentType 请求头.
 * @param {Object} headers 请求头信息
 * @returns {Promise} axios的实例对象
 */
export function common_request({
  url,
  method = "get",
  params = {},
  isFormData = false,
  contentType,
  headers = {},
}) {
  method = method ? method.toLowerCase() : "get";

  if (url.indexOf("http") == 0) {
    url = url;
  } else if (url.indexOf("/") !== 0) {
    // 判断url是否以/开头. 如果不是, 则在链接开头添加/
    url = "/" + url;
  }

  // 判断url是否以VITE_APP_BASE_API开头. 如果不是, 则在链接开头添加VITE_APP_BASE_API
  // if (url.indexOf(import.meta.env.VITE_APP_BASE_API) !== 0) {
  // 	url = import.meta.env.VITE_APP_BASE_API + url;
  // }

  const config = {
    url: url,
    method: method,
    headers: headers,
  };

  if (["post", "put"].includes(config.method)) {
    config.data = qs.stringify(params);
    config.data = params;
    config.headers["Content-Type"] = "application/x-www-form-urlencoded";
  } else {
    config.params = params;
  }

  if (isFormData) {
    try {
      if (!params || Object.keys(params).length === 0) {
        console.error("FormData格式请求中参数不能为空!");
      }
    } catch (error) {
      console.error("FormData格式请求中参数不能为空!");
    }
    config.headers["Content-Type"] = "multipart/form-data";
    config.method = ["get", "delete"].includes(method) ? "post" : method;
    params = objectToFormData(params);
  }

  if (contentType) {
    config.headers["Content-Type"] = contentType;
  }
  // console.log(config);
  return request(config);
}

/**
 * 通用数据删除请求方法
 * @description 该函数提供了一种通用的方式来发送删除数据的 HTTP 请求。它接受一个参数对象，该对象包含了请求的配置URL和请求参数。
 * @param {String} url 请求url
 * @param {String} params 请求携带的参数
 * @returns {Promise} axios的实例对象
 */
export function delete_request({ url, params = {}, isFormData = true }) {
  const config = {
    url: url,
    method: "post",
    headers: {},
  };
  if (isFormData) {
    config.data = qs.stringify(params);
    config.headers["Content-Type"] = "application/x-www-form-urlencoded";
  } else {
    config.data = params;
  }

  return request(config);
}

/**
 * 将对象转换为FormData对象
 * @param {Object} data 数据对象
 * @param {string} prefix 前缀
 * @param {FormData} formData FormData对象
 */
function objectToFormData(data, prefix, formData) {
  formData = formData || new FormData();

  for (const key in data) {
    if (Object.prototype.hasOwnProperty.call(data, key)) {
      const value = data[key];
      const newKey = prefix ? `${prefix}.${key}` : key;

      if (Array.isArray(value)) {
        addNestedArrayToFormData(formData, newKey, value);
      } else if (value instanceof File) {
        formData.append(newKey, value);
      } else if (typeof value === "object") {
        objectToFormData(value, newKey, formData);
      } else {
        formData.append(newKey, value);
      }
    }
  }

  return formData;
}

/**
 * 将嵌套数组转换为对象形式，并添加到FormData对象中
 * @param {FormData} formData FormData对象
 * @param {string} key 字段名
 * @param {Array} arr 数组
 */
function addNestedArrayToFormData(formData, key, arr) {
  for (let i = 0; i < arr.length; i++) {
    const value = arr[i];
    const nestedKey = `${key}[${i}]`;

    if (Array.isArray(value)) {
      addNestedArrayToFormData(formData, nestedKey, value);
    } else if (typeof value === "object") {
      objectToFormData(value, nestedKey, formData);
    } else {
      formData.append(nestedKey, value);
    }
  }
}
